﻿#include "netManger_udp.h"

netManger_udp::netManger_udp(std::function<void (socketMsg *)> localReadyReadFun)
    :event_localReadyRead(localReadyReadFun)
{

}

netManger_udp::~netManger_udp()
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->socket){
            i->socket->close();
            delete i->socket;
        }
    }
}



//无论如何都能获取到用户指针，内部自动协调
netManger_udp::socketMsg netManger_udp::getUser(QString netHost, uint16_t netPort, uint16_t localPort)
{
    ++startNumber;
    //检查列表内是否已经存在这个
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->netHost == netHost && i->netPort == netPort){
            i->localPort = localPort;
            i->signNum = startNumber;
            return *i;
        }
    }

    if(this->userList.length() < USERMAX){  //没有达到容器上线则持续创建UDP模拟客户端
        socketMsg t_sm;
        t_sm.socket = new QUdpSocket;
        t_sm.netHost = netHost;
        t_sm.netPort = netPort;
        t_sm.localPort = localPort;
        t_sm.signNum = startNumber;
        this->userList.append(t_sm);

        uint32_t t_index = this->userList.length() - 1; //计算好偏差数据，直接获取
        QAbstractSocket::connect(t_sm.socket,&QUdpSocket::readyRead,[=](){
            //服务套接字，客户套接字，客户远程转发端口
            if(event_localReadyRead != nullptr){
                this->event_localReadyRead(this->userList.begin() + t_index);
            }
        }); //绑定UDP收到数据

        return t_sm;
    }
    else{
        uint32_t t_minNum = startNumber; //一个足够大的值
        QVector<socketMsg>::iterator t_minI; //保存最小的值对象
        for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){ //查出最小的对象值
            if(i->signNum < t_minNum){
                t_minI = i;
                t_minNum = i->signNum;
            }
        }
        t_minI->netHost = netHost;
        t_minI->netPort = netPort;
        t_minI->localPort = localPort;
        t_minI->signNum = startNumber; //刷新最新的标记
        return *t_minI;
    }

}


//清理所有客户
void netManger_udp::clear()
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(!i->netHost.isEmpty()){
            i->netHost = "";
            i->netPort = 0;
            i->localPort = 0;
            i->signNum = 0;
        }
    }
}


//收到数据,客户端模拟转发
void netManger_udp::event_readyRead(QString netHost,uint16_t netPort, uint16_t localPort, QByteArray data)
{
    netManger_udp::socketMsg t_userMsg = getUser(netHost, netPort, localPort);
    t_userMsg.socket->writeDatagram(data,QHostAddress("127.0.0.1"),localPort);
}
